#include "faiss_adapter_base.h"

#include "impl/AuxIndexStructures.h"
#include "log.h"

VET_INDEX_NAMESPACE_BEGIN

FaissAptBase::FaissAptBase(faiss::Index* p_index , bool b_has_delete)
    : p_base_index_(p_index)
    , b_has_delete_(b_has_delete)
{

}

FaissAptBase::~FaissAptBase()
{

}

int FaissAptBase::InsertVet(
        const float* p_vetcont_array,
        const idx_t* p_vetid_array,
        idx_t i_num)
{
    try
    {
        p_base_index_->add_with_ids(
                    i_num, 
                    p_vetcont_array,
                    p_vetid_array);
    }
    catch(const faiss::FaissException& e)
    {
        log_error("add vector error:%s" , e.what());
        return -1;
    }
    catch(...)
    {
        log_error("unknow error");
        return -1;
    }

    return p_base_index_->ntotal;
}

int FaissAptBase::RemoveVet(const idx_t* p_vetid_array,
                             idx_t i_num)
{
    try
    {
        faiss::IDSelectorArray o_select_array(
                i_num ,
                p_vetid_array);

        return p_base_index_->remove_ids(o_select_array);
    }
    catch(const faiss::FaissException& e)
    {
        log_error("remove vector error:%s" , e.what());
        return -1;
    }
    catch(...)
    {
        log_error("unknow error");
        return -1;
    }
}

int FaissAptBase::UpdateVet(const float* p_vetcont_array,
                                const idx_t* p_vetid_array,
                                idx_t i_num)
{
    log_error("update vet not implemented for this type of index");
    return -1;
}

int FaissAptBase::SearchVet(
        const float* p_query_array,
        idx_t i_top_k,
        idx_t* p_res_vetid_array,
        float* p_res_vetdis_array,
        idx_t i_query_num)
{
    try
    {
        p_base_index_->search(
            i_query_num,
            p_query_array,
            i_top_k,
            p_res_vetdis_array,
            p_res_vetid_array);
        return 0;
    }
    catch(const faiss::FaissException& e)
    {
        log_error("search vector error:%s" , e.what());
        return -1;
    }
    catch(...)
    {
        log_error("unknow error");
        return -1;
    }
}

int FaissAptBase::ExtractVet(
    idx_t i_idx_id,
    float* p_vetcont_array)
{
    if (NULL == p_vetcont_array) {
        return -1;
    }
    
    try
    {
        p_base_index_->reconstruct(
            i_idx_id,
            p_vetcont_array);
        return 0;
    }
    catch(const faiss::FaissException& e)
    {
        log_error("search vector error:%s" , e.what());
        return -2;
    }
    catch(...)
    {
        log_error("unknow error");
        return -1;
    }
}

VET_INDEX_NAMESPACE_END